/**
 * Copyright (C) 2013-2014 the original author or authors.
 */
package com.foreveross.bsl.system.web;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.beanutils.PropertyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.foreveross.bsl.auth.Auth;
import com.foreveross.bsl.auth.service.IdentityService;
import com.foreveross.bsl.common.utils.bean.MailHelper;
import com.foreveross.bsl.common.utils.enums.AccountStatus;
import com.foreveross.bsl.common.utils.enums.AccountType;
import com.foreveross.bsl.common.utils.enums.Status;
import com.foreveross.bsl.common.utils.exception.AppExcType;
import com.foreveross.bsl.common.utils.exception.ApplicationException;
import com.foreveross.bsl.system.application.AccountActivatingCheckCodeApplication;
import com.foreveross.bsl.system.application.AccountApplication;
import com.foreveross.bsl.system.application.AccountInfoApplication;
import com.foreveross.bsl.system.application.vo.AccountActivatingCheckCodeVO;
import com.foreveross.bsl.system.application.vo.AccountInfoDetailVO;
import com.foreveross.bsl.system.application.vo.AccountInfoVO;
import com.foreveross.bsl.system.application.vo.AccountVO;
import com.foreveross.bsl.web.BaseController;

/**
 * @description
 * 
 * @author rening
 * @version v1.0
 * 
 * @2013-6-13
 * 
 */
@Controller
@RequestMapping("/system/account")
public class AccountController extends BaseController {

	@Inject
	private AccountApplication accountApplication;

	@Inject
	private AccountInfoApplication accountInfoApplication;
	

	@Inject
	private AccountActivatingCheckCodeApplication accountActivatingCheckCodeApplication;

	@Autowired
	private IdentityService identityService;

	@ResponseBody
	@RequestMapping("/add")
	public Map<String, String> add(AccountVO account) {
		Map<String, String> result = new HashMap<String, String>();
		accountApplication.saveEntity(account);
		result.put("result", "success");
		return result;
	}

	@ResponseBody
	@RequestMapping("/save")
	public Map<String, String> saveAccount(AccountInfoDetailVO accountInfoDetail, HttpServletRequest request) {

		List list = accountApplication.getEntityByUserName(accountInfoDetail.getUsername());
		Map<String, String> result = new HashMap<String, String>();
		if (list != null && list.size() > 0) {
			throw new ApplicationException(AppExcType.BUS_TYPE, AppExcType.WEB_LAYER, AppExcType.SYS_MODUL, "101", "the username: " + accountInfoDetail.getUsername()
					+ " has already register, please try another one.");
		} else {
			AccountVO account = new AccountVO();
			AccountInfoVO accountInfo = new AccountInfoVO();
			String accountType = AccountType.Normal.getValue();
//			String successAddress = "/system/account/register-success";

			
			try {
				PropertyUtils.copyProperties(account, accountInfoDetail);
			} catch (Exception e) {
				throw new ApplicationException();
			}

			account.setUsername(accountInfoDetail.getAccUsername());
			Md5PasswordEncoder md = new Md5PasswordEncoder();
			String encodePassword = md.encodePassword(accountInfoDetail.getPassword(),
					account.getUsername());
			account.setPassword(encodePassword);
			account.setAccountType(accountType);
			account.setStatus(AccountStatus.Auditing.getValue());
			account = accountApplication.saveEntity(account);
			

//			accountInfo.setAccountId(account.getId());
//			try {
//				PropertyUtils.copyProperties(accountInfo, accountInfoDetail);
//			} catch (Exception e) {
//				throw new ApplicationException();
//			}
			accountInfoDetail.setAccountId(account.getId());
			accountInfo = accountInfoApplication.saveEntity(accountInfoDetail);
			
			MailHelper mailHelper = new MailHelper();
			String checkCode = mailHelper.getCheckCode(account.getUsername());
			String content = mailHelper
					.getEmailContent(account.getUsername(), checkCode);
			boolean b = mailHelper.sendValidateMail(accountInfo.getEmail(), content);

			Date d = new Date();
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
			int expiration_days = 1;

			String expiration = df.format(new Date(d.getTime()
					+ expiration_days * 24 * 60 * 60 * 1000));
			AccountActivatingCheckCodeVO ac = new AccountActivatingCheckCodeVO();
			ac.setAccountId(account.getId());
			ac.setUsername(account.getUsername());
			ac.setCheckCode(checkCode);
			ac.setStatus(Status.YES.getValue());
			ac.setExpiration(expiration);
			accountActivatingCheckCodeApplication.saveEntity(ac);

			request.getSession().setAttribute("checkCode", ac);
			result.put("result", "true");
			if (!b) {
				result.put("email", "false");
			} 
		}
		return result;
	}

	@RequestMapping("/activateAccount")
	public String activateAccount(@RequestParam("checkcode") String checkcode,
			Model model) {

		List<AccountActivatingCheckCodeVO> acs = accountActivatingCheckCodeApplication
				.getEntityByCheckCode(checkcode);
		if (acs == null || acs.isEmpty()) {
			throw new ApplicationException(AppExcType.BUS_TYPE);
		}

		Date d = new Date();
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		Date now = new Date(d.getTime());
		AccountActivatingCheckCodeVO ac = acs.get(0);
		
		Date ed = new Date();
		try {
			ed = df.parse(ac.getExpiration());
		} catch (ParseException e) {
			throw new ApplicationException();
		}

		if (now.before(ed)) {
			AccountVO avo = accountApplication.getEntity(ac
					.getAccountId());
			avo.setStatus(AccountStatus.Normal.getValue());
			accountApplication.updateEntity(avo.getId(), avo);

			ac.setStatus(Status.NO.getValue());
			accountActivatingCheckCodeApplication.updateEntity(
					ac.getId(), ac);
			model.addAttribute("username", ac.getUsername());
		} else {
			throw new ApplicationException(AppExcType.BUS_TYPE, AppExcType.WEB_LAYER, AppExcType.SYS_MODUL, "102", "Sorry, this connection has expired, please re-register, or contact us for administrators");
		}
//			model.addAttribute("activateMessage", "对不起，此连接已经失效，请重新注册，或联系我们管理员");
		return "/account/afterActivate";
	}

	@ResponseBody
	@RequestMapping("/update")
	public Map<String, String> update(AccountVO account) {
		Map<String, String> result = new HashMap<String, String>();
		accountApplication.updateEntity(account.getId(), account);
		result.put("result", "success");
		return result;
	}

	@ResponseBody
	@RequestMapping("/delete")
	public Map<String, Object> delete(String[] ids) {
		Map<String, Object> result = new HashMap<String, Object>();
		if (ids != null) {
			for (int i = 0; i < ids.length; i++) {
				accountApplication.deleteEntity(ids[i]);
			}
		}
		result.put("result", "success");
		return result;
	}

	@ResponseBody
	@RequestMapping("/get")
	public Map<String, Object> get(@RequestParam String id) {
		Map<String, Object> result = new HashMap<String, Object>();
		AccountVO account = accountApplication.getEntity(id);
		result.put("data", account);
		return result;
	}

	@ResponseBody
	@RequestMapping("/login")
	public Map<String, Object> login(@RequestParam String accUsername, @RequestParam String username,
			@RequestParam String password, HttpServletRequest request) {
		Map<String, Object> result = new HashMap<String, Object>();
		String sessionKey = "";
		
		sessionKey = accountApplication.login(accUsername, username, password);
			
		if (sessionKey != null && !"".equals(sessionKey)) {
			request.getSession().setAttribute("sessionKey", sessionKey);
			result.put("result", "true"); // success to login
			// result.put("successAddress", "loginSuccess.html");
		} else {
			throw new ApplicationException(AppExcType.BUS_TYPE);
		}

		return result;
	}

	// @ResponseBody
	@RequestMapping("/logout")
	public String logout(HttpServletRequest request) {
		String sessionKey = (String) request.getSession().getAttribute(
				"sessionKey");
		if (sessionKey != null) {
			accountApplication.logout(sessionKey);
		}
		request.getSession().setAttribute("sessionKey", "");
		return "redirect:login-view";
	}

	@ResponseBody
	@RequestMapping("/reActivateEmail")
	public Map<String, String> reActivate(String username,
			HttpServletRequest request) {
		Map<String, String> result = new HashMap<String, String>();

		HttpSession session = request.getSession();
		if (session != null) {
			Date emailTime = (Date)session.getAttribute("emailTime");
			if(emailTime != null){
				Calendar cal = Calendar.getInstance();
				cal.setTime(emailTime);
				cal.add(Calendar.MINUTE, 5);
				
				Date curDate = new Date();
				if((curDate.getTime() - cal.getTimeInMillis()) < 0){
					throw new ApplicationException("2100103", "please wait for 5 minute");
				}
			}
			
			AccountActivatingCheckCodeVO vo = (AccountActivatingCheckCodeVO) session
					.getAttribute("checkCode");
			if (vo != null) {
				AccountInfoVO acfo = accountInfoApplication
						.getEntityByAccountId(vo.getAccountId());

				MailHelper mailHelper = new MailHelper();
				String checkCode = vo.getCheckCode();
				String content = mailHelper.getEmailContent(vo.getUsername(),
						checkCode);
				boolean b = mailHelper.sendValidateMail(acfo.getEmail(),
						content);
				if(!b){
					throw new ApplicationException(AppExcType.BUS_TYPE);
				}
				session.setAttribute("emailTime", new Date());
				result.put("result", "success");
				return result;
			}
		}

		if (username != null) {
			List<AccountVO> accList = accountApplication.getEntityByUserName(username);
			if (accList == null) {
				throw new ApplicationException(AppExcType.BUS_TYPE);
			}
			AccountVO accountVO = accList.get(0);
			AccountInfoVO acfo = accountInfoApplication.getEntityByAccountId(accountVO.getId());

			MailHelper mailHelper = new MailHelper();
			String checkCode = mailHelper.getCheckCode(accountVO.getUsername());
			String content = mailHelper.getEmailContent(accountVO.getUsername(), checkCode);
			boolean b = mailHelper.sendValidateMail(acfo.getEmail(), content);
			if(b){
				List<AccountActivatingCheckCodeVO> acfos = accountActivatingCheckCodeApplication
						.findRecordsByAccountId(accountVO.getId());
				
				for (AccountActivatingCheckCodeVO vo : acfos) {
					vo.setStatus(Status.NO.getValue());
					accountActivatingCheckCodeApplication.updateEntity(
							vo.getId(), vo);
				}

				Date d = new Date();
				SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
				int expiration_days = 1;
	
				String expiration = df.format(new Date(d.getTime()
						+ expiration_days * 24 * 60 * 60 * 1000));
				AccountActivatingCheckCodeVO ac = new AccountActivatingCheckCodeVO();
				ac.setAccountId(accountVO.getId());
				ac.setUsername(accountVO.getUsername());
				ac.setCheckCode(checkCode);
				ac.setStatus(Status.YES.getValue());
				ac.setExpiration(expiration);
				accountActivatingCheckCodeApplication.saveEntity(ac);
				
				request.getSession().setAttribute("checkCode", ac);
				session.setAttribute("emailTime", new Date());
				result.put("result", "success");
				return result;
			} else {
				throw new ApplicationException(AppExcType.BUS_TYPE);
			}
		} else {
			throw new ApplicationException(AppExcType.BUS_TYPE);
		}
	}

	@RequestMapping("/login-view")
	public String loginView(HttpServletRequest request) {
		return "account/login";
	}

	/**
	 * 此方法描述的是：租户信息页面
	 * 
	 * @author: panhm@foreveross.com
	 * @version: 2013-8-8 下午4:39:39
	 */

	@RequestMapping("/view")
	public String view(HttpServletRequest request, Model model) {
		String sessionKey = (String) request.getSession().getAttribute(
				"sessionKey");
		Object obj = identityService.validateTicket(sessionKey);
		if (obj instanceof Auth) {
			Auth auth = (Auth) obj;
			AccountInfoVO account = accountInfoApplication
					.getEntityByAccountId(auth.getAccountId());
			model.addAttribute("auth", auth);
			model.addAttribute("account", account);
		}
		return "account/accountInfo";
	}

	@RequestMapping("/register-view")
	public String registerView(HttpServletRequest request) {
		return "account/register";
	}

	@RequestMapping("/register-success")
	public String registerSuccess(HttpServletRequest request) {
		return "account/registerSuccess";
	}

	@ResponseBody
	@RequestMapping("/auth")
	public Map<String, Object> auth() {
		Map<String, Object> result = new HashMap<String, Object>();
		this.getCurrentUserId();
		AccountVO account = accountApplication.getEntity(this
				.getCurrentUserId());
		result.put("result", "true");
		result.put("data", account);
		return result;
	}

	@Override
	protected String getModuleMenuName() {
		// TODO Auto-generated method stub
		return "租户服务";
	}
}
